package thread;

// 通过这个代码来演示多线程和单线程相比效率的提升
public class ThreadDemo12 {
    // 串行执行(一个线程完成)
    public static long serial() {
        // 加上一个计时操作
        long begin = System.currentTimeMillis();

        long a = 0;
        for (long i = 0; i < 100_0000_0000L; i++) {
            a++;
        }

        long b = 0;
        for (long i = 0; i < 100_0000_0000L; i++) {
            b++;
        }

        long end = System.currentTimeMillis();
        return end - begin;
    }

    // 并发执行(两个线程完成)
    public static long concurrency() throws InterruptedException {
        // 使用两个线程分别完成自增
        Thread t1 = new Thread(() -> {
           long a = 0;
            for (long i = 0; i < 100_0000_0000L; i++) {
                a++;
            }
        });

        Thread t2 = new Thread(() -> {
            long b = 0;
            for (long i = 0; i < 100_0000_0000L; i++) {
                b++;
            }
        });
        // 计时
        long begin = System.currentTimeMillis();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        long end = System.currentTimeMillis();
        return end - begin;
    }

    public static void main(String[] args) throws InterruptedException {
        // 假设目前有两个变量, 需要把两个变量各自自增 1000w 次 (典型的 CPU 密集型场景)
        // 可以一个线程, 先针对 a 自增, 再针对 b 自增
        long serialTime = 0;
        // 取三次平均值
        for (int i = 0; i < 3; i++) {
            serialTime += serial();
        }
        System.out.println("[serial] 单线程版本执行时间: " + serialTime/3 + " ms");
        // 还可以两个线程, 分别对 a 和 b 自增

        long concurrencyTime = 0;
        // 取三次平均值
        for (int i = 0; i < 3; i++) {
            concurrencyTime += concurrency();
        }
        System.out.println("[concurrency] 多线程版本执行时间: " + concurrencyTime/3 + " ms");
    }
}
